#pragma once

#include <stx/core/string.hpp>

inline namespace stx
{
struct Cout__ final
{
    Task fn_task = [] {};

    constexpr Cout__() noexcept = default;

    // NOLINTNEXTLINE
    Cout__(std::ostream& (*manipulator)(std::ostream&));

    // NOLINTNEXTLINE
    Cout__(auto const& v)
        : fn_task(
              [&]
              {
                  if constexpr (requires { std::cout << v; })
                  {
                      std::cout << v;
                  }
                  else if constexpr (IsConvertibleToAnsiStringView<decltype(v)>)
                  {
                      std::cout << tosv(v);
                  }
                  else if constexpr (IsConvertibleToAnsiString<decltype(v)>)
                  {
                      std::cout << tos(v);
                  }
                  else
                  {
                      static_assert(AlwaysFalse<decltype(v)>);
                  }
              })
    {}
};

struct Cerr__ final
{
    Task fn_task = [] {};

    constexpr Cerr__() noexcept = default;

    // NOLINTNEXTLINE
    Cerr__(std::ostream& (*manipulator)(std::ostream&));

    // NOLINTNEXTLINE
    Cerr__(auto const& v)
        : fn_task(
              [&]
              {
                  if constexpr (requires { std::cout << v; })
                  {
                      std::cerr << v;
                  }
                  else if constexpr (IsConvertibleToAnsiStringView<decltype(v)>)
                  {
                      std::cerr << tosv(v);
                  }
                  else if constexpr (IsConvertibleToAnsiString<decltype(v)>)
                  {
                      std::cerr << tos(v);
                  }
                  else
                  {
                      static_assert(AlwaysFalse<decltype(v)>);
                  }
              })
    {}
};

void cout(Cout__ v1);
void cout(Cout__ v1, Cout__ v2);
void cout(Cout__ v1, Cout__ v2, Cout__ v3);
void cout(Cout__ v1, Cout__ v2, Cout__ v3, Cout__ v4);
void cout(Cout__ v1, Cout__ v2, Cout__ v3, Cout__ v4, Cout__ v5);
void cout(Cout__ v1, Cout__ v2, Cout__ v3, Cout__ v4, Cout__ v5, Cout__ v6);
void cout(Cout__ v1,
          Cout__ v2,
          Cout__ v3,
          Cout__ v4,
          Cout__ v5,
          Cout__ v6,
          Cout__ v7);
void cout(Cout__ v1,
          Cout__ v2,
          Cout__ v3,
          Cout__ v4,
          Cout__ v5,
          Cout__ v6,
          Cout__ v7,
          Cout__ v8);

void cout(Cout__ v1,
          Cout__ v2,
          Cout__ v3,
          Cout__ v4,
          Cout__ v5,
          Cout__ v6,
          Cout__ v7,
          Cout__ v8,
          Cout__ v9);

void cout(Cout__ v1,
          Cout__ v2,
          Cout__ v3,
          Cout__ v4,
          Cout__ v5,
          Cout__ v6,
          Cout__ v7,
          Cout__ v8,
          Cout__ v9,
          Cout__ v10);

void cout(Cout__ v1,
          Cout__ v2,
          Cout__ v3,
          Cout__ v4,
          Cout__ v5,
          Cout__ v6,
          Cout__ v7,
          Cout__ v8,
          Cout__ v9,
          Cout__ v10,
          Cout__ v11);

void cout(Cout__ v1,
          Cout__ v2,
          Cout__ v3,
          Cout__ v4,
          Cout__ v5,
          Cout__ v6,
          Cout__ v7,
          Cout__ v8,
          Cout__ v9,
          Cout__ v10,
          Cout__ v11,
          Cout__ v12);

void cout(Cout__ v1,
          Cout__ v2,
          Cout__ v3,
          Cout__ v4,
          Cout__ v5,
          Cout__ v6,
          Cout__ v7,
          Cout__ v8,
          Cout__ v9,
          Cout__ v10,
          Cout__ v11,
          Cout__ v12,
          Cout__ v13);

void cout(Cout__ v1,
          Cout__ v2,
          Cout__ v3,
          Cout__ v4,
          Cout__ v5,
          Cout__ v6,
          Cout__ v7,
          Cout__ v8,
          Cout__ v9,
          Cout__ v10,
          Cout__ v11,
          Cout__ v12,
          Cout__ v13,
          Cout__ v14);

void cout(Cout__ v1,
          Cout__ v2,
          Cout__ v3,
          Cout__ v4,
          Cout__ v5,
          Cout__ v6,
          Cout__ v7,
          Cout__ v8,
          Cout__ v9,
          Cout__ v10,
          Cout__ v11,
          Cout__ v12,
          Cout__ v13,
          Cout__ v14,
          Cout__ v15);

void cout(Cout__ v1,
          Cout__ v2,
          Cout__ v3,
          Cout__ v4,
          Cout__ v5,
          Cout__ v6,
          Cout__ v7,
          Cout__ v8,
          Cout__ v9,
          Cout__ v10,
          Cout__ v11,
          Cout__ v12,
          Cout__ v13,
          Cout__ v14,
          Cout__ v15,
          Cout__ v16);

void xout();
void xout(Cout__ v1);
void xout(Cout__ v1, Cout__ v2);
void xout(Cout__ v1, Cout__ v2, Cout__ v3);
void xout(Cout__ v1, Cout__ v2, Cout__ v3, Cout__ v4);
void xout(Cout__ v1, Cout__ v2, Cout__ v3, Cout__ v4, Cout__ v5);
void xout(Cout__ v1, Cout__ v2, Cout__ v3, Cout__ v4, Cout__ v5, Cout__ v6);
void xout(Cout__ v1,
          Cout__ v2,
          Cout__ v3,
          Cout__ v4,
          Cout__ v5,
          Cout__ v6,
          Cout__ v7);
void xout(Cout__ v1,
          Cout__ v2,
          Cout__ v3,
          Cout__ v4,
          Cout__ v5,
          Cout__ v6,
          Cout__ v7,
          Cout__ v8);

void xout(Cout__ v1,
          Cout__ v2,
          Cout__ v3,
          Cout__ v4,
          Cout__ v5,
          Cout__ v6,
          Cout__ v7,
          Cout__ v8,
          Cout__ v9);

void xout(Cout__ v1,
          Cout__ v2,
          Cout__ v3,
          Cout__ v4,
          Cout__ v5,
          Cout__ v6,
          Cout__ v7,
          Cout__ v8,
          Cout__ v9,
          Cout__ v10);

void xout(Cout__ v1,
          Cout__ v2,
          Cout__ v3,
          Cout__ v4,
          Cout__ v5,
          Cout__ v6,
          Cout__ v7,
          Cout__ v8,
          Cout__ v9,
          Cout__ v10,
          Cout__ v11);

void xout(Cout__ v1,
          Cout__ v2,
          Cout__ v3,
          Cout__ v4,
          Cout__ v5,
          Cout__ v6,
          Cout__ v7,
          Cout__ v8,
          Cout__ v9,
          Cout__ v10,
          Cout__ v11,
          Cout__ v12);

void xout(Cout__ v1,
          Cout__ v2,
          Cout__ v3,
          Cout__ v4,
          Cout__ v5,
          Cout__ v6,
          Cout__ v7,
          Cout__ v8,
          Cout__ v9,
          Cout__ v10,
          Cout__ v11,
          Cout__ v12,
          Cout__ v13);

void xout(Cout__ v1,
          Cout__ v2,
          Cout__ v3,
          Cout__ v4,
          Cout__ v5,
          Cout__ v6,
          Cout__ v7,
          Cout__ v8,
          Cout__ v9,
          Cout__ v10,
          Cout__ v11,
          Cout__ v12,
          Cout__ v13,
          Cout__ v14);

void xout(Cout__ v1,
          Cout__ v2,
          Cout__ v3,
          Cout__ v4,
          Cout__ v5,
          Cout__ v6,
          Cout__ v7,
          Cout__ v8,
          Cout__ v9,
          Cout__ v10,
          Cout__ v11,
          Cout__ v12,
          Cout__ v13,
          Cout__ v14,
          Cout__ v15);

void cerr(Cerr__ v1);
void cerr(Cerr__ v1, Cerr__ v2);
void cerr(Cerr__ v1, Cerr__ v2, Cerr__ v3);
void cerr(Cerr__ v1, Cerr__ v2, Cerr__ v3, Cerr__ v4);
void cerr(Cerr__ v1, Cerr__ v2, Cerr__ v3, Cerr__ v4, Cerr__ v5);
void cerr(Cerr__ v1, Cerr__ v2, Cerr__ v3, Cerr__ v4, Cerr__ v5, Cerr__ v6);
void cerr(Cerr__ v1,
          Cerr__ v2,
          Cerr__ v3,
          Cerr__ v4,
          Cerr__ v5,
          Cerr__ v6,
          Cerr__ v7);
void cerr(Cerr__ v1,
          Cerr__ v2,
          Cerr__ v3,
          Cerr__ v4,
          Cerr__ v5,
          Cerr__ v6,
          Cerr__ v7,
          Cerr__ v8);

void cerr(Cerr__ v1,
          Cerr__ v2,
          Cerr__ v3,
          Cerr__ v4,
          Cerr__ v5,
          Cerr__ v6,
          Cerr__ v7,
          Cerr__ v8,
          Cerr__ v9);

void cerr(Cerr__ v1,
          Cerr__ v2,
          Cerr__ v3,
          Cerr__ v4,
          Cerr__ v5,
          Cerr__ v6,
          Cerr__ v7,
          Cerr__ v8,
          Cerr__ v9,
          Cerr__ v10);

void cerr(Cerr__ v1,
          Cerr__ v2,
          Cerr__ v3,
          Cerr__ v4,
          Cerr__ v5,
          Cerr__ v6,
          Cerr__ v7,
          Cerr__ v8,
          Cerr__ v9,
          Cerr__ v10,
          Cerr__ v11);

void cerr(Cerr__ v1,
          Cerr__ v2,
          Cerr__ v3,
          Cerr__ v4,
          Cerr__ v5,
          Cerr__ v6,
          Cerr__ v7,
          Cerr__ v8,
          Cerr__ v9,
          Cerr__ v10,
          Cerr__ v11,
          Cerr__ v12);

void cerr(Cerr__ v1,
          Cerr__ v2,
          Cerr__ v3,
          Cerr__ v4,
          Cerr__ v5,
          Cerr__ v6,
          Cerr__ v7,
          Cerr__ v8,
          Cerr__ v9,
          Cerr__ v10,
          Cerr__ v11,
          Cerr__ v12,
          Cerr__ v13);

void cerr(Cerr__ v1,
          Cerr__ v2,
          Cerr__ v3,
          Cerr__ v4,
          Cerr__ v5,
          Cerr__ v6,
          Cerr__ v7,
          Cerr__ v8,
          Cerr__ v9,
          Cerr__ v10,
          Cerr__ v11,
          Cerr__ v12,
          Cerr__ v13,
          Cerr__ v14);

void cerr(Cerr__ v1,
          Cerr__ v2,
          Cerr__ v3,
          Cerr__ v4,
          Cerr__ v5,
          Cerr__ v6,
          Cerr__ v7,
          Cerr__ v8,
          Cerr__ v9,
          Cerr__ v10,
          Cerr__ v11,
          Cerr__ v12,
          Cerr__ v13,
          Cerr__ v14,
          Cerr__ v15);

void cerr(Cerr__ v1,
          Cerr__ v2,
          Cerr__ v3,
          Cerr__ v4,
          Cerr__ v5,
          Cerr__ v6,
          Cerr__ v7,
          Cerr__ v8,
          Cerr__ v9,
          Cerr__ v10,
          Cerr__ v11,
          Cerr__ v12,
          Cerr__ v13,
          Cerr__ v14,
          Cerr__ v15,
          Cerr__ v16);

void xerr();
void xerr(Cerr__ v1);
void xerr(Cerr__ v1, Cerr__ v2);
void xerr(Cerr__ v1, Cerr__ v2, Cerr__ v3);
void xerr(Cerr__ v1, Cerr__ v2, Cerr__ v3, Cerr__ v4);
void xerr(Cerr__ v1, Cerr__ v2, Cerr__ v3, Cerr__ v4, Cerr__ v5);
void xerr(Cerr__ v1, Cerr__ v2, Cerr__ v3, Cerr__ v4, Cerr__ v5, Cerr__ v6);
void xerr(Cerr__ v1,
          Cerr__ v2,
          Cerr__ v3,
          Cerr__ v4,
          Cerr__ v5,
          Cerr__ v6,
          Cerr__ v7);
void xerr(Cerr__ v1,
          Cerr__ v2,
          Cerr__ v3,
          Cerr__ v4,
          Cerr__ v5,
          Cerr__ v6,
          Cerr__ v7,
          Cerr__ v8);

void xerr(Cerr__ v1,
          Cerr__ v2,
          Cerr__ v3,
          Cerr__ v4,
          Cerr__ v5,
          Cerr__ v6,
          Cerr__ v7,
          Cerr__ v8,
          Cerr__ v9);

void xerr(Cerr__ v1,
          Cerr__ v2,
          Cerr__ v3,
          Cerr__ v4,
          Cerr__ v5,
          Cerr__ v6,
          Cerr__ v7,
          Cerr__ v8,
          Cerr__ v9,
          Cerr__ v10);

void xerr(Cerr__ v1,
          Cerr__ v2,
          Cerr__ v3,
          Cerr__ v4,
          Cerr__ v5,
          Cerr__ v6,
          Cerr__ v7,
          Cerr__ v8,
          Cerr__ v9,
          Cerr__ v10,
          Cerr__ v11);

void xerr(Cerr__ v1,
          Cerr__ v2,
          Cerr__ v3,
          Cerr__ v4,
          Cerr__ v5,
          Cerr__ v6,
          Cerr__ v7,
          Cerr__ v8,
          Cerr__ v9,
          Cerr__ v10,
          Cerr__ v11,
          Cerr__ v12);

void xerr(Cerr__ v1,
          Cerr__ v2,
          Cerr__ v3,
          Cerr__ v4,
          Cerr__ v5,
          Cerr__ v6,
          Cerr__ v7,
          Cerr__ v8,
          Cerr__ v9,
          Cerr__ v10,
          Cerr__ v11,
          Cerr__ v12,
          Cerr__ v13);

void xerr(Cerr__ v1,
          Cerr__ v2,
          Cerr__ v3,
          Cerr__ v4,
          Cerr__ v5,
          Cerr__ v6,
          Cerr__ v7,
          Cerr__ v8,
          Cerr__ v9,
          Cerr__ v10,
          Cerr__ v11,
          Cerr__ v12,
          Cerr__ v13,
          Cerr__ v14);

void xerr(Cerr__ v1,
          Cerr__ v2,
          Cerr__ v3,
          Cerr__ v4,
          Cerr__ v5,
          Cerr__ v6,
          Cerr__ v7,
          Cerr__ v8,
          Cerr__ v9,
          Cerr__ v10,
          Cerr__ v11,
          Cerr__ v12,
          Cerr__ v13,
          Cerr__ v14,
          Cerr__ v15);
} // namespace stx